package org.javabasics.reflect;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.security.PrivateKey;

/**
 * Created by LUOLIANG on 2016/9/18.
 * 使用动态代理模拟aop的实现
 */
public class MockAop {
    public static void main(String[] args) {
        Animal target = new Wolf();
        Animal animal = (Animal) MyProxyFactory.getProxy(target);
        animal.info();
        animal.run();
    }
}

class MyProxyFactory {
    //为指定的target生成动态代理对象
    public static Object getProxy(Object target) {
        MyInvocationHandler invocationHandler = new MyInvocationHandler();
        invocationHandler.setTarget(target);
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(), invocationHandler);
    }
}

class MyInvocationHandler implements InvocationHandler {
    //需要被代理的对象
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }

    //执行动态代理的所有方法时，都会被替换成下面的invoke方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        AnimalUtil animalUtil = new AnimalUtil();
        animalUtil.method1();

        //回调target对象的原有方法
        Object result = method.invoke(target, args);

        animalUtil.method2();

        return result;
    }
}

/**
 * 定义一个通用的方法
 */
class AnimalUtil {
    //第一个拦截方法
    public void method1() {
        System.out.println("----模拟第一个通用方法----");
    }

    public void method2() {
        System.out.println("----模拟第二个通用方法----");
    }
}

/**
 * 定义一个类实现接口
 */
class Wolf implements Animal {
    @Override
    public void info() {
        System.out.println("我是风中一匹狼");
    }

    @Override
    public void run() {
        System.out.println("我在奔跑");
    }
}

/**
 * 定义一个动物接口
 */
interface Animal {
    void info();

    void run();
}
